import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JPanel;

public class Level extends JPanel {

	protected static final long serialVersionUID = -6577058583543633816L;

	protected List<List<LevelCase>> mMap;

	protected int mSizeX;

	protected int mSizeY;

	protected int mPacManSpeedField = 40;

	protected int mGhostNormalSpeedField = 40;

	protected int mGhostVulnerableSpeedField = 30;

	private int mGhostIntelligence = 2;

	protected int mPowerBallDurationField = 5000;

	public Level(int sizeX, int sizeY) {
		this.setSizeX(sizeX);
		this.setSizeY(sizeY);
		this.mMap = new ArrayList<List<LevelCase>>();
		this.initMap();
	}

	public void initMap() {
		List<LevelCase> currentLine;
		for (int i = 0; i < this.getSizeX(); i++) {
			currentLine = new ArrayList<LevelCase>();
			for (int j = 0; j < this.getSizeX(); j++) {
				currentLine.add(new LevelCase());
			}

			this.mMap.add(currentLine);
		}

		this.updateGraphicalMap();
	}

	public void updateGraphicalMap() {
		this.setLayout(new GridLayout(this.getSizeY(), 1));

		Dimension size = new Dimension(this.getSizeX() * 20,
				this.getSizeY() * 20);
		this.setSize(size);
		this.setPreferredSize(size);

		this.removeAll();

		// Parcours de toutes les lignes
		Iterator<List<LevelCase>> lineIt = this.mMap.iterator();
		List<LevelCase> currentLine;
		Iterator<LevelCase> caseIt;
		LevelCase currentCase;

		JPanel linePanel;

		while (lineIt.hasNext()) {
			currentLine = lineIt.next();
			linePanel = new JPanel(new GridLayout(1, this.getSizeX()));

			// Parcours de toutes les cases
			caseIt = currentLine.iterator();
			while (caseIt.hasNext()) {
				currentCase = caseIt.next();

				// Ajout de la case au panel de la ligne
				linePanel.add(currentCase);
			}

			this.add(linePanel);
		}

		this.repaint();
	}

	public List<List<LevelCase>> getMap() {
		return mMap;
	}

	public void addRow() {
		this.setSizeX(this.getSizeX() + 1);

		// Parcours de toutes les lignes
		Iterator<List<LevelCase>> lineIt = this.mMap.iterator();
		List<LevelCase> currentLine;

		while (lineIt.hasNext()) {
			currentLine = lineIt.next();

			// Ajout d'une case en fin de ligne
			currentLine.add(new LevelCase());
		}

		// Refresh de la map
		this.updateGraphicalMap();
	}

	public void addLine() {
		this.setSizeY(this.getSizeY() + 1);

		// Création de la nouvelle ligne
		List<LevelCase> newLine = new ArrayList<LevelCase>();
		for (int i = 0; i < this.getSizeX(); i++) {
			// Création de la nouvelle case
			newLine.add(new LevelCase());
		}

		// Ajout de la nouvelle ligne.
		this.mMap.add(newLine);

		// Refresh de la map
		this.updateGraphicalMap();
	}

	public void addLine(List<LevelCase> aLevelCaseLine) {
		this.setSizeY(this.getSizeY() + 1);
		this.setSizeX(aLevelCaseLine.size());

		// Ajout de la nouvelle ligne.
		this.mMap.add(aLevelCaseLine);

		// Refresh de la map
		this.updateGraphicalMap();
	}

	public void removeRow() {
		if (this.getSizeX() > 0) {
			this.setSizeX(this.getSizeX() - 1);

			// Parcours de toutes les lignes
			Iterator<List<LevelCase>> lineIt = this.mMap.iterator();
			List<LevelCase> currentLine;

			while (lineIt.hasNext()) {
				currentLine = lineIt.next();

				// Suppression de la dernière case
				currentLine.remove(currentLine.size() - 1);
			}

			// Refresh de la map
			this.updateGraphicalMap();
		}
	}

	public void removeLine() {
		if (this.getSizeY() > 0) {
			this.setSizeY(this.getSizeY() - 1);

			// Suppression de la dernière ligne.
			this.mMap.remove(this.mMap.size() - 1);

			// Refresh de la map
			this.updateGraphicalMap();
		}
	}

	public int getSizeX() {
		return mSizeX;
	}

	public void setSizeX(int sizeX) {
		this.mSizeX = sizeX;
	}

	public int getSizeY() {
		return mSizeY;
	}

	public void setSizeY(int sizeY) {
		this.mSizeY = sizeY;
	}

	public Integer getPacManSpeedField() {
		return mPacManSpeedField;
	}

	public void setPacManSpeedField(int mPacManSpeedField) {
		this.mPacManSpeedField = mPacManSpeedField;
	}

	public Integer getGhostNormalSpeedField() {
		return mGhostNormalSpeedField;
	}

	public void setGhostNormalSpeedField(int mGhostNormalSpeedField) {
		this.mGhostNormalSpeedField = mGhostNormalSpeedField;
	}

	public Integer getGhostVulnerableSpeedField() {
		return mGhostVulnerableSpeedField;
	}

	public void setGhostVulnerableSpeedField(int mGhostVulnerableSpeedField) {
		this.mGhostVulnerableSpeedField = mGhostVulnerableSpeedField;
	}

	public Integer getPowerBallDurationField() {
		return mPowerBallDurationField;
	}

	public void setPowerBallDurationField(int mPowerBallDurationField) {
		this.mPowerBallDurationField = mPowerBallDurationField;
	}

	public Integer getGhostIntelligence() {
		return mGhostIntelligence;
	}

	public void setGhostIntelligence(int mGhostIntelligence) {
		this.mGhostIntelligence = mGhostIntelligence;
	}
}
